﻿using AutoMapper;
using BackData;
using Domain;
using Infratructure;
using MD5Hash;
using MediatR;
using Microsoft.IdentityModel.Tokens;
using Rabbit.API.Application.Command.User;
using Rabbit.API.DTOs;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using System.Threading;

namespace Rabbit.API.Application.Handler.User
{
    public class UserLoginHandler:IRequestHandler<UserLoginCommand,APIResult<LoginDTO>>
    {
        private readonly IRepository<UserModel> userway;
        private readonly IRepository<RoleModel> roleway;
        private readonly ILogger<UserLoginHandler> log;
        private readonly IMapper mapper;
        private readonly IConfiguration configuration;

        public UserLoginHandler(IRepository<UserModel> userway,IRepository<RoleModel> roleway,ILogger<UserLoginHandler> log,IMapper mapper,IConfiguration configuration)
        {
            this.userway = userway;
            this.roleway = roleway;
            this.log = log;
            this.mapper = mapper;
            this.configuration = configuration;
        }
        /// <summary>
        /// 用户登录实现
        /// </summary>
        /// <param name="request">账号密码</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns>用户数据</returns>
        public Task<APIResult<LoginDTO>> Handle(UserLoginCommand request, CancellationToken cancellationToken)
        {
            APIResult<LoginDTO> res = new APIResult<LoginDTO>();
            try
            {
                var user = userway.GetAll().FirstOrDefault(x => x.UserName == request.UserName);
                if(user!=null)
                {
                    if(user.UserPwd==request.UserPwd.GetMD5())
                    {
                        log.LogInformation($"用户{request.UserName}于{DateTime.UtcNow}登录成功");
                        var rolename = roleway.GetAll().FirstOrDefault(x => x.Id == user.RoleId).RoleName;
                        var result = mapper.Map<LoginDTO>(user);
                        result.TokenString = CreateTokenString();
                        result.RoleName = rolename;
                        res.Message = $"用户{request.UserName}于{DateTime.UtcNow}登录成功";
                        res.Data = result;
                        res.Num = StateCode.OK;
                        
                    }
                    else
                    {
                        res.Message = $"密码错误,请重试";
                        res.Num = StateCode.Fail;
                    }
                }
                else
                {
                    res.Message = $"用户名不存在";
                    res.Num = StateCode.Fail;
                }
                return Task.FromResult(res);
            }
            catch (Exception ex)
            {
                log.LogError($"登录时发生异常{ex.Message}");
                throw;
            }
        }

        /// <summary>/// 生成 JWT Token（令牌）/// </summary>/// <returns></returns>
        private string CreateTokenString()
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes(configuration["JwtConfiguration:PrivideKey"]);
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: configuration["JwtConfiguration:Issuer"],
                audience: configuration["JwtConfiguration:Audience"],
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
